package com.css.bjdt_core.validation.util;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.concurrent.ConcurrentHashMap;
/**
 * @Description:  [细粒度互斥key锁]   
 * @UpdateRemark: [去掉单例模式，每个模块都可以有自己的key锁，否则会造成key相同，锁相同，但并不需要互斥的情况]  
 */
public class KeyLocks {

	private ConcurrentHashMap<String, LockRef> locks = new ConcurrentHashMap<String, LockRef>();

	private ReferenceQueue<Object> queue = new ReferenceQueue<Object>();

	public Object getLock(String key) {
		if (!locks.containsKey(key)) {
			synchronized (locks) {
				if (!locks.containsKey(key)) {
					clearCache();
					Object lock = new byte[0];
					LockRef lockRef = new LockRef(lock, queue, key);
					locks.put(key, lockRef);
				}
			}
		}
		return locks.get(key).get();
	}

	private void clearCache() {
		LockRef ref = null;
		while ((ref = (LockRef) queue.poll()) != null) {
			locks.remove(ref.getKey());
		}
	}

	private class LockRef extends SoftReference<Object> {
		private String key;

		public LockRef(Object ref, ReferenceQueue<Object> q, String key) {
			super(ref, q);
			this.key = key;
		}

		public String getKey() {
			return key;
		}
	}
}